<?php

namespace App\Models\OpenShop\InvestmentPromotion;

use App\Enums\OpenShop\InvestmentPromotion\MainProcessEnum;
use App\Enums\OpenShop\InvestmentPromotion\OpenShopCacheEnum;
use App\Models\BaseModel;
use App\Models\OpenShop\Common\OpenShopOrderManagerModel;
use App\Models\OpenShop\ShopCheckAccept\OpenShopCheckAcceptModel;
use App\Models\OpenShop\ShopEngineeringConstruction\OpenShopEngineeringConstructionModel;
use App\Models\OpenShop\SiteLocation\OpenShopSiteLocationModel;
use App\Models\OpenShop\StartBusiness\OpenShopStartBusinessModel;
use App\Models\Shop\ShopModel;
use App\Models\Traits\KfUid;
use App\Service\OpenShop\Feishu\MissionTemplateService;
use App\Service\OpenShop\UserContractService;
use Closure;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class OpenShopMainProcessModel extends BaseModel
{
    use KfUid;

    protected $table = 'open_shop_main_process';

    public static function booted()
    {
        static::addGlobalScope('orderById', function (Builder $builder) {
            $builder->orderBy('open_shop_main_process.id', 'desc');
        });
    }

    protected $fillable = [
        'shopId',
        'step',
        'orderNo',
        'pid',
        'childOrder',
        'locationPid',
        'childLocationOrder',
        'stepStatusLists',
        'nowStepStatus',
        'startFeeTime',
        'managePrice',
        'parentId',
        'type'
    ];

    // childType
    const CHILD_TYPE_MAIN  = 0;
    const CHILD_TYPE_CHILD = 1;

    /**
     * 新增记录
     */
    public function addData()
    {
        $arr = [];
        foreach ($this->fillable as $field) {
            if ($this->$field === null) {
                continue;
            }

            $arr[$field] = $this->$field;
        }

        $model = self::query()->create($arr);

        // 主订单的pid，置为自己id
        if ($model->childOrder == MainProcessEnum::CHILD_ORDER_0) {
            $model->pid = $model->id;
            $model->save();
        }

//        // 迁址订单
//        if ($model->childLocationOrder == MainProcessEnum::CHILD_ORDER_0) {
//            $model->childLocationOrder = $model->id;
//            $model->save();
//        }


        return $model;
    }

    /**
     * @return HasOne
     */
    public function signOrderRel(): HasOne
    {
        return $this->hasOne(OpenShopSignOrderModel::class, "mainProcessId", "id");
    }

    /**
     * @return HasOne
     */
    public function shopRel(): HasOne
    {
        return $this->hasOne(ShopModel::class, "id", "shopId");
    }

    /**
     * 所属子订单lists
     * @return HasMany
     */
    public function childOrdersRel(): HasMany
    {
        return $this->hasMany(OpenShopMainProcessModel::class, 'pid', 'id')
                    ->where('childOrder', MainProcessEnum::CHILD_ORDER_1);
    }

    /**
     * 所属子订单lists
     * @return HasMany
     */
    public function childLocationOrdersRel(): HasMany
    {
        return $this->hasMany(OpenShopMainProcessModel::class, 'locationPid', 'id')
                    ->where('childLocationOrder', MainProcessEnum::CHILD_ORDER_1);
    }

    /**
     * 所属主订单
     * @return HasOne
     */
    public function parentOrdersRel(): HasOne
    {
        return $this->hasOne(OpenShopMainProcessModel::class, 'id', 'pid');
    }

    /**
     * 迁址所属主订单
     * @return HasOne
     */
    public function parentLocationOrdersRel(): HasOne
    {
        return $this->hasOne(OpenShopMainProcessModel::class, 'id', 'locationPid');
    }

    /**
     * 通过shopId获取主id
     * @param int $shopId
     * @return int
     */
    public static function getIdByShopId(int $shopId): int
    {
        return (int)self::query()->where('shopId', $shopId)->orderBy('id', 'desc')->value('id');
    }

    /**
     * 更新shopId
     * @param int $id
     * @param int $shopId
     * @return int
     */
    public static function saveShopId(int $id, int $shopId): int
    {
        return self::query()->where('id', $id)->update(['shopId' => $shopId]);
    }

    /**
     * 获取关联的orderNos
     * @return array
     */
    public function getRelationsOrderNos(): array
    {
        if ($this->childOrder == MainProcessEnum::CHILD_ORDER_0) {
            return $this->childOrdersRel->pluck('orderNo')->toArray();
        } else {
            $orderNo = (string)optional($this->parentOrdersRel)->orderNo;
            return $orderNo ? [$orderNo] : [];
        }
    }

    /**
     * 获取关联的orderNos
     * @return array
     */
    public function getRelationsLocationOrderNos(): array
    {
        if ($this->childLocationOrder == MainProcessEnum::CHILD_ORDER_0) {
            return $this->childLocationOrdersRel->pluck('orderNo')->toArray();
        } else {
            $orderNo = (string)optional($this->parentLocationOrdersRel)->orderNo;
            return $orderNo ? [$orderNo] : [];
        }
    }


    /**
     * 开店选址关联
     *
     * @return HasOne
     */
    public function shopLocationRel(): HasOne
    {
        return $this->hasOne(OpenShopLocationModel::class, "orderNo", "orderNo");
    }


    /**
     * 空间设计关联
     *
     * @return HasOne
     */
    public function spaceDesignRel(): HasOne
    {
        return $this->hasOne(OpenShopSpaceDesignModel::class, "orderNo", "orderNo");
    }

    /**
     * 营建阶段关联
     *
     * @return HasOne
     */
    public function engineeringConstructionRel(): HasOne
    {
        return $this->hasOne(OpenShopEngineeringConstructionModel::class, "orderNo", "orderNo");
    }

    /**
     * 营建阶段关联
     *
     * @return HasOne
     */
    public function startBusinessRel(): HasOne
    {
        return $this->hasOne(OpenShopStartBusinessModel::class, "orderNo", "orderNo");
    }

    /**
     * 验收关联
     *
     * @return HasOne
     */
    public function checkAcceptRel(): HasOne
    {
        return $this->hasOne(OpenShopCheckAcceptModel::class, "orderNo", "orderNo");
    }

    /**
     * 关联流程日志
     *
     * @return HasMany
     */
    public function processDetailRel(): HasMany
    {
        return $this->hasMany(OpenShopProcessDetailModel::class, "mainProcessId", "id");
    }

    /**
     * 关联负责人
     *
     * @return HasMany
     */
    public function orderManagerRel(): HasMany
    {
        return $this->hasMany(OpenShopOrderManagerModel::class, "mainProcessId", "id");
    }

    /**
     * 更新nowStepStatus
     * @param string $orderNo
     * @param int $stepStatus
     * @return bool
     */
    public static function updateNowStepStatus(string $orderNo, int $stepStatus): bool
    {
        $main = self::query()->where('orderNo', $orderNo)->first();
        if (!$main) {
            return false;
        }

        $dbStepStatusSort  = MissionTemplateService::getSortByStepStatus($main->nowStepStatus);
        $nowStepStatusSort = MissionTemplateService::getSortByStepStatus($stepStatus);
        if ($dbStepStatusSort >= $nowStepStatusSort) {

            // 数据库的任务更往后，不执行
            return false;
        }

        $main->nowStepStatus = $stepStatus;
        return $main->save();
    }

    /**
     * 更新店铺管理费、日期
     * @param string $orderNo
     * @param int $startFeeTime
     * @param int $managePrice
     * @return void
     */
    public static function updateFee(string $orderNo, int $startFeeTime, int $managePrice = 0): void
    {
        if (!$managePrice) {
            $managePrice = UserContractService::getManagementCostEveryYear($orderNo);
        }

        $main = OpenShopMainProcessModel::query()->where('orderNo', $orderNo)->first();

        if (!$main) {
            return;
        }

        if ($main->startFeeTime != 0 && $startFeeTime != $main->startFeeTime) {
            Log::warning("updateFee conflict shopId: {$main->shopId} {$main->id} ori:{$main->startFeeTime} new:{$startFeeTime}");
        }

        $main->update([
            'startFeeTime' => $startFeeTime,
            'managePrice'  => $managePrice
        ]);
    }

    /**
     * 关联用户身份证信息
     *
     * @return HasOne
     */
    public function userIdentityCardRel(): HasOne
    {
        return $this->hasOne(OpenShopUserIdentityCardModel::class, "orderNo", "orderNo");
    }

    /**
     * 用户工作经验
     *
     * @return HasOne
     */
    public function userExperienceRel(): HasOne
    {
        return $this->hasOne(OpenShopUserExperienceModel::class, "orderNo", "orderNo");
    }

    /**
     * 关联合同信息
     *
     * @return HasOne
     */
    public function userContractRel(): HasOne
    {
        return $this->hasOne(OpenShopUserContractModel::class, "orderNo", "orderNo");
    }

    /**
     * 关联合同信息
     *
     * @return HasMany
     */
    public function userContractsRel(): HasMany
    {
        return $this->hasMany(OpenShopUserContractModel::class, "orderNo", "orderNo");
    }

    /**
     * 关联订单日志
     *
     * @return HasMany
     */
    public function openShopSignOrderLogModelRel(): HasMany
    {
        return $this->hasMany(OpenShopSignOrderLogModel::class, "orderId", "id");
    }

    /**
     * 关联用户基本信息
     *
     * @return HasOne
     */
    public function userBaseInfoRel(): HasOne
    {
        return $this->hasOne(OpenShopUserBaseInfoModel::class, "orderNo", "orderNo");
    }


    /**
     * @return HasOne
     */
    public function openShopSiteLocationRel(): HasOne
    {
        return $this->hasOne(OpenShopSiteLocationModel::class, "mainProcessId", "id");
    }

    public function identityCardRel(): HasOne
    {
        return $this->hasOne(OpenShopUserIdentityCardModel::class, "orderNo", "orderNo");
    }

    /**
     * 通过店铺id查询对应门店模型类型-商场还是街边
     * @param $shopId
     * @return Builder|Model|object|null
     */
    public static function getShopModelType($shopId)
    {
        return self::query()
                   ->with('openShopSiteLocationRel')
                   ->where('shopId', $shopId)
                   ->first();
    }


    /**
     * 查询迁址主单
     * @param int $shopId
     */
    public static function getMainOrder(int $shopId)
    {
        return OpenShopMainProcessModel::query()
                                       ->where('shopId', $shopId)
                                       ->where('childLocationOrder', 0)
                                       ->first();
    }

    /**
     * 对比当前状态
     * @param int $compareStepStatus
     * @return string
     */
    public function compareStepStatusSort(int $compareStepStatus): string
    {
        $now = MissionTemplateService::getSortByStepStatus($this->nowStepStatus);
        $compare= MissionTemplateService::getSortByStepStatus($compareStepStatus);

        if ($now > $compare) {
            return '>';
        }

        if ($now == $compare) {
            return '=';
        }

        return '<';
    }
}
